using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WIA;
using WIAVIDEOLib;
using System.IO;
using WindowsLive.Writer.Api;

namespace WebcamSnapshotPlugin
{
    public partial class WebcamSnapshotInsertForm : Form
    {
        /// <summary>
        /// ID of the WIA-Device to use. Set by CommonDialog
        /// </summary>
        public string DeviceId;

        /// <summary>
        /// class-internal variable to hold tempfile path to captured snapshot
        /// </summary>
        string jpgFile;
        /// <summary>
        /// Name of the tempfile for Snapshot from video-stream
        /// </summary>
        public string SnapshotFile
        {
            get
            {
                return jpgFile;
            }
            set
            {
                jpgFile = value;
            }
        }
        
        /// <summary>
        /// Captured snapshot from video-stream
        /// </summary>
        public Image SnapshotImage
        {
            get
            {
                return pictureBoxSnapshot.Image;
            }
        }

        /// <summary>
        /// WIA-Class for video-stream
        /// </summary>
        private WiaVideoClass wiaVideo;
        

        /// <summary>
        /// standard-constructor as created by visual studio
        /// </summary>
        public WebcamSnapshotInsertForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// action after click on "Play"-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// disable play and config button
        /// enable pause and snapshot button
        /// start video-stream
        /// </remarks>
        private void btbPlay_Click(object sender, EventArgs e)
        {
            btbPlay.Enabled = false;
            btnPause.Enabled = true;
            btnCapture.Enabled = true;
            btnConfig.Enabled = false;
            wiaVideo.Play();
        }
        

        /// <summary> Instantiate the video interface and create overlay. </summary>
        private bool CreateVideo()
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                wiaVideo = new WiaVideoClass();
                wiaVideo.ImagesDirectory = "c:\\temp";

                wiaVideo.CreateVideoByWiaDevID(DeviceId, panelVideo.Handle, 0, 1);	// overlay into video panel

                this.Text += " - Device selected"; 
                btnPause.Enabled = true;
                btbPlay.Enabled = false;
                btnCapture.Enabled = true;
                btnConfig.Enabled = false;
                return true;
            }
            catch
            {
                if (wiaVideo != null)
                {
                    PluginDiagnostics.DisplayError("Webcam Snapshot Error","VideoStream could not be created.");
                }
                return false;
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary> Take a picture from video stream. </summary>
        private void SnapPicture()
        {
            try
            {
                DisposePicure();

                wiaVideo.TakePicture(out jpgFile);			// call IWiaVideo::TakePicture
                if (jpgFile != null)
                {
                    pictureBoxSnapshot.SizeMode = PictureBoxSizeMode.Zoom;
                    pictureBoxSnapshot.Image = Image.FromFile(jpgFile);	// load jpeg file into preview
                    btnInsertIntoBlog.Enabled = true;
                }
            }
            catch (Exception) {
                PluginDiagnostics.DisplayError("Webcam Snapshot Error", "Could not take Snapshot.");
            }
        }

        /// <summary> Dispose current picture, this sample just deletes the snap file. </summary>
        private void DisposePicure()
        {
            try
            {
                Image oldImg = pictureBoxSnapshot.Image;		// release previous picture
                pictureBoxSnapshot.Image = null;
                if (oldImg != null)
                    oldImg.Dispose();

                if (jpgFile != null)				// delete jpg file on disk
                    File.Delete(jpgFile);

                jpgFile = null;
            }
            catch (Exception) { }
            finally { jpgFile = null; }
        }

        /// <summary>
        /// Show device-selection dialog, if device is not yet selected
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebcamSnapshotInsertForm_Load(object sender, EventArgs e)
        {
            if (DeviceId.Length == 0)
            {
                //btnConfig_Click(null, null);
                PluginDiagnostics.DisplayError ( "No Device selected", "Please select a video device in the plugin options." );
                this.Close ();
            }
            else
            {
                CreateVideo ();
            }
        }

        /// <summary>
        /// Show device-selection dialog
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfig_Click(object sender, EventArgs e)
        {
            try
            {
                CommonDialogClass class1 = new CommonDialogClass();
                Device d = class1.ShowSelectDevice(WiaDeviceType.VideoDeviceType, true, false);
                if (d != null)
                {
                    DeviceId = d.DeviceID;
                }
                WebcamSnapshotInsertForm_FormClosing(null, null);
                CreateVideo();
            }
            catch (Exception ex)
            {
                PluginDiagnostics.DisplayError("Webcam Snapshot Error", "Device selection failed: " + ex.Message);
            }
        }

        /// <summary>
        /// action after click on pause-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// pause video-stream
        /// enable play and config button
        /// disable pause and capture button
        /// </remarks>
        private void btnPause_Click(object sender, EventArgs e)
        {
            wiaVideo.Pause();
            btbPlay.Enabled = true;
            btnPause.Enabled = false;
            btnCapture.Enabled = false;
            btnConfig.Enabled = true;
        }

        /// <summary>
        /// Close the dialog with DialogResult Cancel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        /// <summary>
        /// Capture picture from video-stream
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCapture_Click(object sender, EventArgs e)
        {
            btnCapture.Enabled = false;
            SnapPicture();
            btnCapture.Enabled = true;
        }

        
        /// <summary>
        /// Close the dialog with DialogResult OK
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnInsertIntoBlog_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        /// <summary>
        /// Do cleanup before closing dialog
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebcamSnapshotInsertForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if ((wiaVideo != null) && (wiaVideo.GetCurrentState() != WIAVIDEO_STATE.WIAVIDEO_NO_VIDEO))
            {
                wiaVideo.DestroyVideo();
                while (wiaVideo.GetCurrentState() == WIAVIDEO_STATE.WIAVIDEO_DESTROYING_VIDEO)
                {
                    //wait for wiaVideo being destroyed
                }
                wiaVideo = null;
            }
        }

        /// <summary>
        /// Timer for Video-Resize-Delay
        /// </summary>
        Timer timer1 = new Timer();

        /// <summary>
        /// When video-placeholder gets resized start timer. When timer fires apply new video-stream
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// if we did this without timer the video would be continously reassigned while resizing the placeholder
        /// </remarks>
        private void panelVideo_Resize(object sender, EventArgs e)
        {
            if (timer1.Enabled == false)
            {
                timer1.Interval = 1000;
                timer1.Tick += new EventHandler(timer1_Tick);
                timer1.Enabled = true;
            }
        }

        /// <summary>
        /// Apply a new video-stream to placeholder
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            WebcamSnapshotInsertForm_FormClosing(null, null);
            CreateVideo();
            this.Focus();
        }
    }
}